#ifndef LEARNING_H_
#define LEARNING_H_

#include "Defines.h"
#include "Activation.h"

/*-----------------------------------------------------------------------------
 *  Aprendizados
 *-----------------------------------------------------------------------------*/
#define SUPERVISIONED 1 // Aprendizado supervisionado

/*-----------------------------------------------------------------------------
 *  Máximos e mínimos da taxa de aprendizado
 *-----------------------------------------------------------------------------*/
#define MAX     1.0
#define MIN     0.01
#define ALPHA   50000

/*
 * =====================================================================================
 *        Class:  Learning
 *  Description:  Classe que representa um aprendizado
 * =====================================================================================
 */
class Learning
{

public:

    /*-----------------------------------------------------------------------------
     *  Constrói um aprendizado dando seu tipo e a função de ativação
     *-----------------------------------------------------------------------------*/
    Learning(int type, ActivationPtr activation);

    /*-----------------------------------------------------------------------------
     *  Calcula a taxa de aprendizado
     *-----------------------------------------------------------------------------*/
    void calcLearningRate(uint i);

    /*-----------------------------------------------------------------------------
     *  Retorna a variação do peso dado a entrada e o erro de saída
     *-----------------------------------------------------------------------------*/
    double delta(double input, double error);

    /*-----------------------------------------------------------------------------
     *  Calcula o erro na camada de saída
     *-----------------------------------------------------------------------------*/
    double error(double expected, double output, double sum);

    /*-----------------------------------------------------------------------------
     *  Calcula o erro nas camadas escondidas
     *-----------------------------------------------------------------------------*/
    double error(vdoublePtr errors, vdoublePtr weights, double sum);

private:

    /*-----------------------------------------------------------------------------
     *  Tipo
     *-----------------------------------------------------------------------------*/
    int type;

    /*-----------------------------------------------------------------------------
     *  Taxa de aprendizado
     *-----------------------------------------------------------------------------*/
    double learningRate;

    /*-----------------------------------------------------------------------------
     *  Função de ativação
     *-----------------------------------------------------------------------------*/
    ActivationPtr activation;

};

/*-----------------------------------------------------------------------------
 *  Ponteiro
 *-----------------------------------------------------------------------------*/
typedef boost::shared_ptr<Learning> LearningPtr;

#endif /* LEARNING_H_ */
